[Add] Chat Bubble Limit Cvars#971
[Add] Chat Bubble Limit Cvars#971Vaaankas wants to merge 3 commits intoWWhiteDreamProject:masterfrom
Conversation
WalkthroughДобавлены CVars для лимита символов и максимума пузырьков; добавлено усечение отображаемого содержимого пузырьков и интеграция этого лимита в клиентский UI, контроллер чата и серверную TTS-логику; добавлен утилитарный метод для замены содержимого внутри тегов в SharedChatSystem. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Content.Client/Chat/UI/SpeechBubble.cs (1)
307-350: Критическая проблема: отсутствует усечение в fancy-пути.В fancy-пути метода
FancyTextSpeechBubble.BuildBubble(строки 307-350) не применяется усечение сообщения. СодержимоеBubbleContentизвлекается на строке 323, но методTruncateWrappedMessageне вызывается перед этим.Это приводит к несогласованному поведению:
- Текстовые пузырьки (TextSpeechBubble) и не-fancy пузырьки ограничены
SingleBubbleCharLimit- Fancy пузырьки могут превышать лимит символов
Это нарушает цель PR по ограничению длины речевых пузырьков.
🔎 Предлагаемое исправление
Добавьте вызов
TruncateWrappedMessageперед извлечением содержимого пузырька:}; //We'll be honest. *Yes* this is hacky. Doing this in a cleaner way would require a bottom-up refactor of how saycode handles sending chat messages. -Myr + message = TruncateWrappedMessage(message, SingleBubbleCharLimit); // White Dream bubbleHeader.SetMessage(FormatSpeech(SharedChatSystem.GetStringInsideTag(message, "BubbleHeader"), fontColor, "Bedstead")); // WWDP EDIT // LESS USELESS ONE LINER FUNCS PLS bubbleContent.SetMessage(FormatSpeech(SharedChatSystem.GetStringInsideTag(message, "BubbleContent"), fontColor, "Bedstead")); // WWDP EDIT
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
Content.Client/Chat/UI/SpeechBubble.csContent.Client/UserInterface/Systems/Chat/ChatUIController.csContent.Server/_White/TTS/TTSSystem.csContent.Shared/Chat/SharedChatSystem.csContent.Shared/_White/CCVar/WhiteCVars.Chat.cs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/ru-RU/_white/cards/danger.ftl:1-1
Timestamp: 2025-10-22T20:31:06.235Z
Learning: В PR по EvacPod для WWhiteDreamProject/wwdpublic: в ru-RU локализациях допустим осознанный сленг сообщества SS13 (напр., «дистры»), если он не ломает отображение и используется последовательно; не блокировать PR, предлагать необязательный follow-up (глоссарий/проверка консистентности).
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/en-US/_white/cards/hobby.ftl:5-5
Timestamp: 2025-10-22T20:13:31.389Z
Learning: В PR по EvacPod для репозитория WWhiteDreamProject/wwdpublic: если опечатка в ключе локализации (например, card-ep_hobby_mashrooms) не влияет на отображение и используется последовательно, автор предпочитает не блокировать PR; вместо этого предлагать необязательный follow-up issue.
Learnt from: Vaaankas
Repo: WWhiteDreamProject/wwdpublic PR: 269
File: Content.Server/_White/Examine/ExaminableCharacterSystem.cs:0-0
Timestamp: 2025-03-03T15:02:14.394Z
Learning: User Vaaankas prefers communication in Russian language. Respond to them in Russian rather than English.
📚 Learning: 2025-09-24T18:18:06.673Z
Learnt from: RedFoxIV
Repo: WWhiteDreamProject/wwdpublic PR: 849
File: Content.Client/_White/UserInterface/WindowTracker.cs:1-5
Timestamp: 2025-09-24T18:18:06.673Z
Learning: The WWhiteDreamProject codebase uses GlobalUsings.cs files to provide global using directives. IoCManager is available throughout Content.Client without explicit using Robust.Shared.IoC; directive due to global usings configuration. Code analysis should account for global usings when checking for missing using statements.
Applied to files:
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
🧬 Code graph analysis (4)
Content.Shared/Chat/SharedChatSystem.cs (1)
Content.Client/Chat/UI/SpeechBubble.cs (1)
ChatMessage(231-245)
Content.Server/_White/TTS/TTSSystem.cs (1)
Content.Shared/_White/CCVar/WhiteCVars.Chat.cs (1)
WhiteCVars(5-21)
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs (1)
Content.Shared/_White/CCVar/WhiteCVars.Chat.cs (1)
WhiteCVars(5-21)
Content.Client/Chat/UI/SpeechBubble.cs (1)
Content.Shared/Chat/SharedChatSystem.cs (3)
SharedChatSystem(16-392)GetStringInsideTag(351-360)SetStringInsideTag(364-375)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Test Packaging
- GitHub Check: build (ubuntu-latest)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML Linter
- GitHub Check: YAML map schema validator
🔇 Additional comments (10)
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs (3)
111-111: LGTM!Свойство корректно читает значение из WhiteCVars.SingleBubbleCharLimit, обеспечивая динамическую настройку лимита символов.
121-121: Объясните изменение константы BubbleDelayFactor.BubbleDelayFactor изменён с динамического значения, зависящего от SingleBubbleCharLimit, на фиксированное
0.8f / 100. Комментарий "White Dream" не поясняет причину изменения.Если это сделано для фиксации скорости появления пузырьков независимо от лимита символов — добавьте поясняющий комментарий. В противном случае, это изменение может быть непреднамеренным.
126-126: LGTM!Свойство корректно читает значение из WhiteCVars.SpeechBubbleCap для динамической настройки максимального количества речевых пузырьков.
Content.Shared/_White/CCVar/WhiteCVars.Chat.cs (1)
16-20: LGTM!CVars корректно определены:
chat.bubble_character_limit(43 символа) ограничивает длину текста в речевом пузырькеchat.bubble_max_count(1 пузырёк) ограничивает количество одновременных пузырьковФлаги
SERVER | REPLICATEDобеспечивают синхронизацию значений между сервером и клиентами. Значения по умолчанию соответствуют описанию PR.Content.Shared/Chat/SharedChatSystem.cs (1)
362-376: LGTM!Метод
SetStringInsideTagкорректно реализован:
- Находит границы тега в
WrappedMessage- Удаляет старое содержимое между открывающим и закрывающим тегами
- Вставляет новое содержимое на то же место
- Возвращает исходное сообщение, если теги не найдены (безопасное поведение)
Реализация симметрична существующему методу
GetStringInsideTagи используется вTruncateWrappedMessageдля усечения текста в речевых пузырьках.Content.Client/Chat/UI/SpeechBubble.cs (4)
55-59: LGTM!Свойство
SingleBubbleCharLimitкорректно читает значение из WhiteCVars, обеспечивая динамическую настройку лимита символов для речевых пузырьков.
231-245: LGTM!Метод
TruncateWrappedMessageкорректно реализован:
- Извлекает текст из тега
BubbleContent- Проверяет длину и возвращает исходное сообщение, если оно в пределах лимита
- Усекает текст до
maxLength, удаляет завершающую пунктуацию и добавляет многоточие- Использует
SetStringInsideTagдля обновления содержимого сообщенияЛогика усечения выглядит правильно.
262-262: LGTM!Усечение сообщения применяется до форматирования, что обеспечивает соблюдение лимита символов в текстовых речевых пузырьках.
294-294: LGTM!Усечение сообщения применяется в не-fancy ветке, обеспечивая соблюдение лимита символов.
Content.Server/_White/TTS/TTSSystem.cs (1)
27-27: Добавьте объяснение для множителя × 2 или используйте значение без умножения.
MaxMessageCharsустановлен вSingleBubbleCharLimit * 2(86 символов по умолчанию), но сообщения в UI обрезаются до 43 символов с помощьюTruncateWrappedMessage()вSpeechBubble.cs. Неясно, почему TTS должна принимать сообщения длиной до 86 символов, если они будут отображены только в одном пузырьке с лимитом 43 символа. Если это сделано специально (например, для промежуточной обработки или совместимости), добавьте комментарий с объяснением. Если нет — рассмотрите использованиеSingleBubbleCharLimitбез умножения.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/ru-RU/_white/cards/danger.ftl:1-1
Timestamp: 2025-10-22T20:31:06.235Z
Learning: В PR по EvacPod для WWhiteDreamProject/wwdpublic: в ru-RU локализациях допустим осознанный сленг сообщества SS13 (напр., «дистры»), если он не ломает отображение и используется последовательно; не блокировать PR, предлагать необязательный follow-up (глоссарий/проверка консистентности).
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/en-US/_white/cards/hobby.ftl:5-5
Timestamp: 2025-10-22T20:13:31.389Z
Learning: В PR по EvacPod для репозитория WWhiteDreamProject/wwdpublic: если опечатка в ключе локализации (например, card-ep_hobby_mashrooms) не влияет на отображение и используется последовательно, автор предпочитает не блокировать PR; вместо этого предлагать необязательный follow-up issue.
Learnt from: Vaaankas
Repo: WWhiteDreamProject/wwdpublic PR: 269
File: Content.Server/_White/Examine/ExaminableCharacterSystem.cs:0-0
Timestamp: 2025-03-03T15:02:14.394Z
Learning: User Vaaankas prefers communication in Russian language. Respond to them in Russian rather than English.
📚 Learning: 2025-09-24T18:18:06.673Z
Learnt from: RedFoxIV
Repo: WWhiteDreamProject/wwdpublic PR: 849
File: Content.Client/_White/UserInterface/WindowTracker.cs:1-5
Timestamp: 2025-09-24T18:18:06.673Z
Learning: The WWhiteDreamProject codebase uses GlobalUsings.cs files to provide global using directives. IoCManager is available throughout Content.Client without explicit using Robust.Shared.IoC; directive due to global usings configuration. Code analysis should account for global usings when checking for missing using statements.
Applied to files:
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
🧬 Code graph analysis (1)
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs (2)
Content.Shared/_White/CCVar/WhiteCVars.Chat.cs (1)
WhiteCVars(5-21)Content.Client/Chat/UI/SpeechBubble.cs (1)
FadeNow(199-205)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: Test Packaging
- GitHub Check: YAML map schema validator
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML Linter
🔇 Additional comments (4)
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs (4)
18-18: Импорт добавлен корректно.Импорт необходим для доступа к WhiteCVars, используемым в этом файле.
111-111: Переход на динамическую конфигурацию выполнен корректно.Замена константы на свойство, читающее CVar, позволяет динамически изменять лимит символов в пузырьках. Частота обращения к этому свойству низкая, поэтому влияние на производительность минимально.
126-126: Переход на динамическую конфигурацию выполнен корректно.Замена константы на свойство, читающее CVar, позволяет динамически изменять максимальное количество пузырьков. Реализация соответствует целям PR.
121-121: Тайминг пузырьков отделён от настраиваемого лимита символов.BubbleDelayFactor жёстко закодирован как 0.8f / 100 = 0.008, но SingleBubbleCharLimit является серверной переменной конфигурации (текущее значение 43 символа, изменяемо). Это означает:
- При изменении SingleBubbleCharLimit на сервере задержка отображения пузырьков не будет масштабироваться вместе с новым лимитом
- Временно́е поведение (0.544 сек для 43-символьного сообщения) не связано с его ограничением на отображение
Убедитесь, что это разделение логики является намеренным решением для проекта White Dream.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
Content.Server/_White/TTS/TTSSystem.cs (1)
27-27: Рассмотрите возможность кэширования значения.Свойство
MaxMessageCharsвызываетGetCVar()при каждом событии речи (line 44). Аналогично паттерну с_isEnabled(line 32), можно закэшировать значение в поле и обновлять его через_cfg.OnValueChanged:+private int _maxMessageChars; private bool _isEnabled; public override void Initialize() { _cfg.OnValueChanged(WhiteCVars.TTSEnabled, v => _isEnabled = v, true); + _cfg.OnValueChanged(WhiteCVars.SingleBubbleCharLimit, v => _maxMessageChars = v * 2, true);Затем использовать
_maxMessageCharsвместо свойства. Впрочем, учитывая относительно низкую частоту событий речи, текущая реализация может быть приемлемой.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
Content.Client/Chat/UI/SpeechBubble.csContent.Client/UserInterface/Systems/Chat/ChatUIController.csContent.Server/_White/TTS/TTSSystem.csContent.Shared/Chat/SharedChatSystem.csContent.Shared/_White/CCVar/WhiteCVars.Chat.cs
🚧 Files skipped from review as they are similar to previous changes (4)
- Content.Shared/_White/CCVar/WhiteCVars.Chat.cs
- Content.Shared/Chat/SharedChatSystem.cs
- Content.Client/Chat/UI/SpeechBubble.cs
- Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/ru-RU/_white/cards/danger.ftl:1-1
Timestamp: 2025-10-22T20:31:06.235Z
Learning: В PR по EvacPod для WWhiteDreamProject/wwdpublic: в ru-RU локализациях допустим осознанный сленг сообщества SS13 (напр., «дистры»), если он не ломает отображение и используется последовательно; не блокировать PR, предлагать необязательный follow-up (глоссарий/проверка консистентности).
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/en-US/_white/cards/hobby.ftl:5-5
Timestamp: 2025-10-22T20:13:31.389Z
Learning: В PR по EvacPod для репозитория WWhiteDreamProject/wwdpublic: если опечатка в ключе локализации (например, card-ep_hobby_mashrooms) не влияет на отображение и используется последовательно, автор предпочитает не блокировать PR; вместо этого предлагать необязательный follow-up issue.
Learnt from: Vaaankas
Repo: WWhiteDreamProject/wwdpublic PR: 269
File: Content.Server/_White/Examine/ExaminableCharacterSystem.cs:0-0
Timestamp: 2025-03-03T15:02:14.394Z
Learning: User Vaaankas prefers communication in Russian language. Respond to them in Russian rather than English.
🧬 Code graph analysis (1)
Content.Server/_White/TTS/TTSSystem.cs (1)
Content.Shared/_White/CCVar/WhiteCVars.Chat.cs (1)
WhiteCVars(5-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: Test Packaging
- GitHub Check: YAML Linter
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML map schema validator
| [Dependency] private readonly LanguageSystem _language = default!; | ||
|
|
||
| private const int MaxMessageChars = 100 * 2; // same as SingleBubbleCharLimit * 2 | ||
| private int MaxMessageChars => _cfg.GetCVar(WhiteCVars.SingleBubbleCharLimit) * 2; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Поиск файла TTSSystem.cs и WhiteCVars.cs
find . -type f -name "TTSSystem.cs" -o -name "WhiteCVars.cs" | head -20Repository: WWhiteDreamProject/wwdpublic
Length of output: 197
🏁 Script executed:
#!/bin/bash
# Поиск файлов, содержащих SingleBubbleCharLimit
rg "SingleBubbleCharLimit" -l --type=csRepository: WWhiteDreamProject/wwdpublic
Length of output: 258
🏁 Script executed:
#!/bin/bash
# Проверка содержимого файла TTSSystem.cs около строки 27
rg -B 10 -A 10 "MaxMessageChars" Content.Server/_White/TTS/TTSSystem.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 1587
🏁 Script executed:
#!/bin/bash
# Найти определение SingleBubbleCharLimit в WhiteCVars
rg -B 2 -A 2 "SingleBubbleCharLimit" Content.Shared/_White/CCVar/WhiteCVars.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 54
🏁 Script executed:
#!/bin/bash
# Найти определение TTSEnabled для сравнения флагов
rg -B 2 -A 2 "TTSEnabled" Content.Shared/_White/CCVar/WhiteCVars.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 54
🏁 Script executed:
#!/bin/bash
# Проверить все CVAR определения в файле WhiteCVars для понимания паттерна
cat Content.Shared/_White/CCVar/WhiteCVars.cs | head -100Repository: WWhiteDreamProject/wwdpublic
Length of output: 631
🏁 Script executed:
#!/bin/bash
# Найти все файлы WhiteCVars.*
find . -type f -name "WhiteCVars*.cs" | xargs ls -laRepository: WWhiteDreamProject/wwdpublic
Length of output: 1477
🏁 Script executed:
#!/bin/bash
# Прочитать WhiteCVars.Chat.cs
cat Content.Shared/_White/CCVar/WhiteCVars.Chat.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 908
🏁 Script executed:
#!/bin/bash
# Прочитать WhiteCVars.TTS.cs
cat Content.Shared/_White/CCVar/WhiteCVars.TTS.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 1799
🏁 Script executed:
#!/bin/bash
# Поиск других примеров, где серверный код читает CLIENT CVAR
rg -B 3 -A 3 "GetCVar.*CVar\.CLIENT" --type=cs | head -50Repository: WWhiteDreamProject/wwdpublic
Length of output: 54
🏁 Script executed:
#!/bin/bash
# Проверить доступ к GetCVar в серверном контексте для CLIENT-only CVAR
rg "IConfigurationManager.*GetCVar" --type=cs -A 2 | head -50Repository: WWhiteDreamProject/wwdpublic
Length of output: 800
🏁 Script executed:
#!/bin/bash
# Проверить как GetCVar работает с CLIENT-only CVARs
# Найти примеры использования GetCVar с CLIENT флагом на сервере
rg "GetCVar.*SingleBubbleCharLimit|GetCVar.*ColoredBubbleChat|GetCVar.*ChatFancyFont" --type=cs -B 2 -A 2Repository: WWhiteDreamProject/wwdpublic
Length of output: 1861
🏁 Script executed:
#!/bin/bash
# Проверить документацию или комментарии про множитель * 2
rg -B 5 -A 5 "MaxMessageChars|SingleBubbleCharLimit.*\*.*2" Content.Server/_White/TTS/TTSSystem.csRepository: WWhiteDreamProject/wwdpublic
Length of output: 988
🏁 Script executed:
#!/bin/bash
# Проверить, есть ли другие примеры в TTSSystem.cs, где используется MaxMessageChars
cat -n Content.Server/_White/TTS/TTSSystem.cs | grep -i "maxmessagechars\|singlebubble"Repository: WWhiteDreamProject/wwdpublic
Length of output: 238
Исправьте доступность CVAR на сервере.
SingleBubbleCharLimit определён с флагами CVar.CLIENT | CVar.ARCHIVE (без CVar.SERVER или CVar.REPLICATED). Серверный код читает эту переменную через GetCVar(), но для CLIENT-only CVAR будет возвращаться только значение по умолчанию (43), независимо от конфигурации клиента. Это несогласовано с TTSEnabled, которая правильно использует флаг CVar.SERVER | CVar.REPLICATED.
Чтобы исправить:
- Добавьте флаг
CVar.REPLICATEDв определениеSingleBubbleCharLimitвWhiteCVars.Chat.cs, либо переместите вWhiteCVars.TTS.csс флагомCVar.SERVER | CVar.REPLICATED. - Добавьте комментарий, объясняющий множитель
* 2в строке 27 — почему сервер использует двойное значение лимита по сравнению с клиентом. - Рассмотрите кэширование
MaxMessageCharsчерезOnValueChanged(как для_isEnabled) вместо вычисления свойства на каждый вызов.
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |

Добавлены цвары chat.bubble_character_limit и chat.bubble_max_count.
Для уменьшения засорения экрана им установлены пониженные значения: 43 символа (2 строки) и максимум 1 одновременно над головой космонавтика.
🆑 vanx